"""BLE service lifecycle management module."""

import asyncio
import logging
from typing import Optional, Dict, Any
from enum import Enum
import os
import signal

logger = logging.getLogger(__name__)


class BLEServiceStatus(Enum):
    """BLE service status enumeration."""
    ACTIVE = "active"
    DISABLED = "disabled"
    STARTING = "starting"
    STOPPING = "stopping"
    ERROR = "error"


class BLEServiceManager:
    """Manage BLE service lifecycle."""
    
    def __init__(self, ble_server=None):
        """
        Initialize BLE service manager.
        
        Args:
            ble_server: BLE GATT server instance
        """
        self.ble_server = ble_server
        self._status = BLEServiceStatus.DISABLED
        self._force_mode: Optional[str] = None  # None, "enabled", "disabled"
        self._service_task: Optional[asyncio.Task] = None
        self._cleanup_done = False
        
    async def start_service(self) -> bool:
        """
        Start BLE service.
        
        Returns:
            True if service started successfully, False otherwise
        """
        if self._force_mode == "disabled":
            logger.info("BLE service start blocked by force_mode=disabled")
            return False
            
        if self._status == BLEServiceStatus.ACTIVE:
            logger.warning("BLE service already active")
            return True
            
        try:
            self._status = BLEServiceStatus.STARTING
            logger.info("Starting BLE service...")
            
            if self.ble_server:
                # Start the BLE GATT server
                await self.ble_server.start()
                self._cleanup_done = False
                
            self._status = BLEServiceStatus.ACTIVE
            logger.info("BLE service started successfully")
            return True
            
        except Exception as e:
            logger.error(f"Failed to start BLE service: {e}")
            self._status = BLEServiceStatus.ERROR
            return False
            
    async def stop_service(self) -> bool:
        """
        Stop BLE service.
        
        Returns:
            True if service stopped successfully, False otherwise
        """
        if self._force_mode == "enabled":
            logger.info("BLE service stop blocked by force_mode=enabled")
            return False
            
        if self._status == BLEServiceStatus.DISABLED:
            logger.warning("BLE service already disabled")
            return True
            
        try:
            self._status = BLEServiceStatus.STOPPING
            logger.info("Stopping BLE service...")
            
            if self.ble_server:
                # Stop the BLE GATT server
                await self.ble_server.stop()
                
            # Cleanup resources
            await self.cleanup_resources()
            
            self._status = BLEServiceStatus.DISABLED
            logger.info("BLE service stopped successfully")
            return True
            
        except Exception as e:
            logger.error(f"Failed to stop BLE service: {e}")
            self._status = BLEServiceStatus.ERROR
            return False
            
    async def cleanup_resources(self):
        """Clean up Bluetooth resources."""
        if self._cleanup_done:
            return
            
        try:
            logger.info("Cleaning up BLE resources...")
            
            # Stop advertising if running
            try:
                # Using hciconfig to disable advertising
                proc = await asyncio.create_subprocess_exec(
                    'hciconfig', 'hci0', 'noleadv',
                    stdout=asyncio.subprocess.PIPE,
                    stderr=asyncio.subprocess.PIPE
                )
                await proc.communicate()
            except FileNotFoundError:
                logger.debug("hciconfig not available, skipping advertising cleanup")
            except Exception as e:
                logger.warning(f"Error stopping advertising: {e}")
                
            # Release any held resources
            if self.ble_server and hasattr(self.ble_server, 'cleanup'):
                await self.ble_server.cleanup()
                
            self._cleanup_done = True
            logger.info("BLE resources cleaned up")
            
        except Exception as e:
            logger.error(f"Error during resource cleanup: {e}")
            
    def get_service_status(self) -> BLEServiceStatus:
        """
        Get current BLE service status.
        
        Returns:
            Current service status
        """
        return self._status
        
    def set_force_mode(self, mode: Optional[str]):
        """
        Set force mode for BLE service.
        
        Args:
            mode: "enabled", "disabled", or None for auto mode
        """
        if mode not in [None, "enabled", "disabled"]:
            raise ValueError(f"Invalid force mode: {mode}")
            
        old_mode = self._force_mode
        self._force_mode = mode
        logger.info(f"BLE force mode changed: {old_mode} -> {mode}")
        
    def get_force_mode(self) -> Optional[str]:
        """Get current force mode."""
        return self._force_mode
        
    async def restart_service(self) -> bool:
        """
        Restart BLE service.
        
        Returns:
            True if service restarted successfully, False otherwise
        """
        logger.info("Restarting BLE service...")
        
        # Stop service
        if not await self.stop_service():
            logger.error("Failed to stop service during restart")
            return False
            
        # Wait a moment
        await asyncio.sleep(2)
        
        # Start service
        if not await self.start_service():
            logger.error("Failed to start service during restart")
            return False
            
        logger.info("BLE service restarted successfully")
        return True
        
    def is_active(self) -> bool:
        """Check if BLE service is active."""
        return self._status == BLEServiceStatus.ACTIVE
        
    def is_disabled(self) -> bool:
        """Check if BLE service is disabled."""
        return self._status == BLEServiceStatus.DISABLED
        
    def get_status_info(self) -> Dict[str, Any]:
        """
        Get detailed status information.
        
        Returns:
            Dictionary with status details
        """
        return {
            "status": self._status.value,
            "force_mode": self._force_mode,
            "is_active": self.is_active(),
            "is_disabled": self.is_disabled(),
            "has_server": self.ble_server is not None
        }